package com.lht.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lht.admin.constants.DataValidConstant;
import com.lht.admin.dao.ProductDao;
import com.lht.admin.entity.FileUploadEntity;
import com.lht.admin.entity.ProductEntity;
import com.lht.admin.entity.SysUserEntity;
import com.lht.admin.service.CommonService;
import com.lht.admin.service.FileUploadService;
import com.lht.admin.service.ProductService;
import com.lht.admin.utils.ListUtil;
import com.lht.admin.utils.QueryPlus;
import com.lht.admin.utils.R;
import com.lht.admin.utils.StringUtils;
import com.lht.admin.utils.oss.AliyunOssFileUtil;
import com.lht.admin.vo.OptionsVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;


/**
 * 贷款产品表Service实现类
 *
 * @author ZhengZhanWu
 * @date 2020-01-06 23:44:52
 */
@Slf4j
@Service("productService")
public class ProductServiceImpl extends ServiceImpl<ProductDao, ProductEntity> implements ProductService {

    @Resource
    private FileUploadService fileUploadService;

    @Resource
    private AliyunOssFileUtil aliyunOssFileUtil;

    @Resource
    private CommonService commonService;


    @Override
    public List<ProductEntity> queryAll(Map<String, Object> params) {
        return baseMapper.queryAll(params);
    }

    @Override
    public Page queryPage(Map<String, Object> params) {
        //排序
        params.put("sidx", "T.id");
        params.put("asc", false);
        Page<ProductEntity> page = new QueryPlus<ProductEntity>(params).getPage();

        List<ProductEntity> values = baseMapper.selectProductPage(page, params);
        return page.setRecords(values);


    }

    @Override
    public boolean add(ProductEntity product) {
        return this.save(product);
    }

    @Override
    public boolean update(ProductEntity product) {
        return this.updateById(product);
    }

    @Override
    public boolean delete(Long id) {
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(Long[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }


    @Override
    public String uploadFile(MultipartFile file, Long userId) {
        String url = null;
        try (InputStream stream = file.getInputStream()) {

            String fileName = System.currentTimeMillis() + file.getOriginalFilename();

            url = aliyunOssFileUtil.uploadFile(stream, fileName);


            Date date = new Date();
            FileUploadEntity info = new FileUploadEntity();
            info.setOriginName(file.getOriginalFilename());
            info.setNewName(fileName);
            info.setBizeType("sys");
            info.setSourceUserId(userId);
            info.setCreateAt(date);
            info.setUpdateAt(date);
            info.setPath(url);
            info.setSize(file.getSize());
            info.setFormat(getSuffix(fileName));
            fileUploadService.add(info);
        } catch (Exception e) {
            log.error("Function[uploadFile]", e);
        }

        log.info("Function[uploadFile] upload:{} as {}", file.getOriginalFilename(), url);

        return url;
    }


    @Override
    public R importData(MultipartFile file, SysUserEntity operator) {
        if (null == file) {
            return R.error("必须选择文件");
        }
        log.info("Function[importData] file:{}", file.getOriginalFilename());

        String fileName = file.getOriginalFilename();
        if (!fileName.toLowerCase().endsWith(".xlsx")) {
            return R.error("必须为.xlsx后缀的excel文件");
        }

        OptionsVO optionValues = commonService.getOptionValues(operator);

        int success = 0;
        int failure = 0;
        try {
            InputStream inputStream = file.getInputStream();
            Workbook wb = new XSSFWorkbook(inputStream);
            Sheet sheetAt = wb.getSheetAt(0);
            int rowNumbers = sheetAt.getLastRowNum() + 1;
            Row temp = sheetAt.getRow(0);
            if (temp == null) {
                log.warn("importExcel", "导入失败，文件为空");
                return null;
            }

            List<ProductEntity> list = new ArrayList<>();
            // int cells = temp.getPhysicalNumberOfCells();
            for (int row = 0; row < rowNumbers; row++) {
                Row r = sheetAt.getRow(row);
                //for (int col = 0; col < cells; col++) {
                //    Cell cell = r.getCell(col);
                //    log.info(getCellValueAsStr(cell, ""));
                //}

                if (row == 0 || r.getLastCellNum() != 7) {
                    continue;
                }

                Date date = new Date();
                ProductEntity product = new ProductEntity();

                product.setTitle(getCellValueAsStr(r.getCell(0), ""));
                String bankName = getCellValueAsStr(r.getCell(1), "");
                product.setLoanBankId(getBankId(optionValues.getLoanBankList(), bankName));
                product.setLoanBankName(bankName);

                Double fuckingYear = Double.parseDouble(getCellValueAsStr(r.getCell(2), "0"));
                product.setYears(fuckingYear.intValue());
                Double fuckingMaxQuota = Double.parseDouble(getCellValueAsStr(r.getCell(3), "0"));
                product.setMaxQuota(fuckingMaxQuota.intValue());
                product.setLoanRate(new BigDecimal(getCellValueAsStr(r.getCell(4), "0")));
                String rateValue = getCellValueAsStr(r.getCell(5), "0");
                product.setTaxLevel(dealWithRate(optionValues.getTaxLevelList(), rateValue));

                product.setDetails(getCellValueAsStr(r.getCell(6), " "));
                product.setUpdateAt(date);
                product.setUpdateUserId(operator.getUserId());
                product.setCreateAt(date);
                product.setCreateUserId(operator.getUserId());
                product.setIsDelete(DataValidConstant.IS_DELETE_FALSE_STR);

                if (checkInfo(product)) {
                    list.add(product);
                    success++;
                } else {
                    failure++;
                }
            }


            log.info("Function[fuck] values: {}", JSON.toJSONString(list));
            saveBatch(list);
        } catch (Exception e) {
            log.error("Function[importData]", e);
        }

        String desc = "成功:" + success + "条数据,失败:" + failure + "条数据";
        return R.ok(desc);
    }


    private Long getBankId(List<OptionsVO.OptionVO> loanBankList, String bankName) {
        if (ListUtil.isEmpty(loanBankList)) {
            return null;
        }

        Object bankId = null;
        for (OptionsVO.OptionVO vo : loanBankList) {
            if (vo.getLabel().equalsIgnoreCase(bankName)) {
                bankId = vo.getValue();
                break;
            }
        }

        return null == bankId ? null : Long.parseLong(String.valueOf(bankId));
    }


    private String dealWithRate(List<OptionsVO.OptionVO> rateList, String rate) {
        if (null == rate || "".equalsIgnoreCase(rate.trim())) {
            return null;
        }

        List<String> values = new ArrayList<>();
        String[] arr = rate.split(",");

        for (String each : arr) {
            Object target = null;
            for (OptionsVO.OptionVO vo : rateList) {
                if (vo.getLabel().equalsIgnoreCase(each)) {
                    target = vo.getValue();
                    break;
                }
            }

            values.add(String.valueOf(target));
        }

        StringBuilder builder = new StringBuilder();

        for (int i = 0, size = values.size(); i < size; i++) {
            builder.append(values.get(i));
            if (i < size - 1) {
                builder.append(",");
            }
        }

        return builder.toString();
    }

    private boolean checkInfo(ProductEntity productEntity) {
        if (isEmptyStr(productEntity.getTaxLevel())) {
            return false;
        }

        if (isEmptyStr(productEntity.getTitle())) {
            return false;
        }

        if (productEntity.getLoanBankId() == null) {
            return false;
        }

        if (productEntity.getYears() == null) {
            return false;
        }

        if (productEntity.getMaxQuota() == null) {
            return false;
        }

        if (isEmptyStr(productEntity.getTaxLevel())) {
            return false;
        }

        if (productEntity.getLoanRate() == null) {
            return false;
        }

        return true;
    }

    private boolean isEmptyStr(String value) {
        return null == value || "".equalsIgnoreCase(value.trim());
    }

    private String getCellValueAsStr(Cell cell, String defValue) {
        if (cell == null) {
            return defValue;
        }

        int cellType = cell.getCellType();
        switch (cellType) {
            case Cell.CELL_TYPE_NUMERIC:
                return String.valueOf(cell.getNumericCellValue());
            case Cell.CELL_TYPE_STRING:
                return String.valueOf(cell.getStringCellValue());
        }

        return defValue;
    }

    private String getSuffix(String fileName) {
        if (StringUtils.isEmpty(fileName)) {
            return null;
        }

        int i = fileName.lastIndexOf(".");

        return fileName.substring(i + 1);
    }


}
